Skip to content

syntax_theme_file: preview code with a syntect .tmTheme file - #1227

Open
matthewhadley wants to merge 3 commits into
Canop:mainfrom
matthewhadley:custom-syntax-theme
Open

matthewhadley wants to merge 3 commits into
Canop:mainfrom
matthewhadley:custom-syntax-theme

Conversation

@matthewhadley

Copy link
Copy Markdown
Contributor

Code previews can only use the seven themes syntect bundles (#318). Since broot already highlights with syntect, any .tmTheme file, the format bat and Sublime Text read, works too. This adds a syntax_theme_file conf entry pointing at one:

syntax_theme_file: ~/.config/bat/themes/my-theme.tmTheme
  • The path takes ~, and a relative path is resolved from the conf file declaring it, as imports are.
  • The file is loaded once, when the AppContext is built, with ThemeSet::get_theme. A file which can't be read or parsed is a conf error (invalid syntax theme file "...": ...), as an unknown syntax_theme name already is.
  • The file takes precedence over syntax_theme from the conf. The bundled skins all set one (dark-blue.hjson sets MochaDark), so otherwise a user would have to find and remove that line before their file had any effect. :set_syntax_theme still replaces it at runtime, since it sets syntax_theme, which then wins.
  • Syntaxer::highlighter_for now ties its lifetime to the AppContext as well as itself, as the theme can come from either.

The conf docs gain a paragraph on the entry.

An alternative some of us had been using is a preview transformer piping code through bat (possible since #1225). A real theme is better: a tty preview can't be filtered, so a content search (c/foo) doesn't narrow the preview to matching lines or mark the matches, while a syntect-highlighted text preview does.

Tested on macOS with nightfox's terafox .tmTheme: code previews render in its colours, content searches filter the preview and highlight matches with the skin's preview_match, and a missing file stops startup with the error above. cargo test and cargo clippy pass.

Fixes #318

🤖 Generated with Claude Code

A path to a .tmTheme file, the format syntect and bat read, gives code
previews a theme of the user's own rather than one of the seven bundled
ones. A relative path is resolved from the conf file declaring it, like
imports. The file takes precedence over a syntax_theme set in conf, as
broot's own skins set one; :set_syntax_theme still replaces it at runtime.
A file which can't be read or parsed is a conf error.

Fixes Canop#318

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@Canop

Canop commented Oct 11, 2026

Copy link
Copy Markdown
Owner

Stop there and read CONTRIBUTING.md

Your Claude should have alerted you at when reading the AGENTS.md file

@matthewhadley

Copy link
Copy Markdown
Contributor Author

Hi @Canop apologies I missed that. I do obviously use Claude etc in my day-to-day. I've also looked at https://dystroy.org/blog/contributing/ and understand the burden excessive PR volume/noise can make.

While I believe this PR is well scoped, I'll understand if you want to close it out.

@Canop

Canop commented Oct 11, 2026 •

Copy link
Copy Markdown
Owner

This PR is well scoped. Just like what your previous one, which is why I didn't react immediately.

But this isn't a job task, I'm not payed to review Claude contributions on my FOSS programs. So I ask people to at least write the text of issues and PR themselves, having made the effort to completely understand the problem.

I don't think I'll close this one but I'd like people to take such project like an opportunity to use their brain to build things and overcome difficulties, which becomes harder and harder at work.

@Canop

Canop commented Oct 16, 2026 •

Copy link
Copy Markdown
Owner

Taken as it, there would be some disappointment as ansi or base16 colors of bat wouldn't work because they use RGBA colors with an alpha to 00 or 01 (as in #318).

So I suggest this PR also changes Region::from_syntect in text_view.rs to handle such colors, eg

pub fn from_syntect(region: &(Style, &str)) -> Self {
    let c = region.0.foreground;
    let fg = match c.a {
        0 => Some(Color::AnsiValue(c.r)),
        1 => None,
        _ => Some(Color::Rgb { r: c.r, g: c.g, b: c.b }),
    };
    ...
}

I would also ensure it's possible to unset this, and that a later theme preference isn't overriden by a previous theme_file one.

Colours with an alpha of 0 or 1, as in bat's ansi and base16 themes,
are read as a terminal palette index and as the default foreground.

syntax_theme and syntax_theme_file now replace each other as conf files
are read, so the last one read wins, and an empty syntax_theme_file
unsets it.
@matthewhadley

Copy link
Copy Markdown
Contributor Author

Thanks, all done:

  • bat's ansi and base16 themes: Region::from_syntect now reads the alpha byte the way you suggested.
  • Unsetting: syntax_theme_file: "" clears a value set by an earlier conf file. Setting syntax_theme in a later file also replaces it, and the later setting wins.

Note that with the default setup, the skin's syntax_theme: MochaDark now beats a syntax_theme_file set in conf.hjson. The docs suggest putting syntax_theme_file in the skin file your conf.hjson imports (e.g. skins/dark-blue.hjson).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Custom Preview Themes

2 participants